package com.hospital.hms.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.map.MapUtil;
import com.hospital.hms.dao.mapper.DoctorWorkPlanDao;
import com.hospital.hms.dao.mapper.DoctorWorkPlanScheduleDao;
import com.hospital.hms.pojo.DoctorWorkPlanSchedule;
import com.hospital.hms.service.DoctorWorkPlanSchduleService;


import com.hospital.hms.utils.Constants;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.*;

@Service
public class DoctorWorkPlanSchduleServiceImpl implements DoctorWorkPlanSchduleService {
    private String WORK_PLAN_SCHEDULE_KEY = Constants.WORK_PLAN_SCHEDULE_KEY;




    /**
     * 定义一个不可变的时间段映射，表示医生出诊的时间段
     * 时段 1: 08:00
     * 时段 2: 08:30
     * ...
     */
    private static final Map<String, String> APPOINTMENT_SLOT = Map.ofEntries(
            new AbstractMap.SimpleEntry<>("1", "08:00"),
            new AbstractMap.SimpleEntry<>("2", "08:30"),
            new AbstractMap.SimpleEntry<>("3", "09:00"),
            new AbstractMap.SimpleEntry<>("4", "09:30"),
            new AbstractMap.SimpleEntry<>("5", "10:00"),
            new AbstractMap.SimpleEntry<>("6", "10:30"),
            new AbstractMap.SimpleEntry<>("7", "11:00"),
            new AbstractMap.SimpleEntry<>("8", "11:30"),
            new AbstractMap.SimpleEntry<>("9", "13:00"),
            new AbstractMap.SimpleEntry<>("10", "13:30"),
            new AbstractMap.SimpleEntry<>("11", "14:00"),
            new AbstractMap.SimpleEntry<>("12", "14:30"),
            new AbstractMap.SimpleEntry<>("13", "15:00"),
            new AbstractMap.SimpleEntry<>("14", "15:30"),
            new AbstractMap.SimpleEntry<>("15", "16:00")
    );

    @Autowired
    private DoctorWorkPlanScheduleDao doctorWorkPlanScheduleDao;

    @Autowired
    private DoctorWorkPlanDao doctorWorkPlanDao;

    @Autowired
    RedisTemplate redisTemplate;


    private void insertDoctorWorkPlanSchedule(ArrayList<DoctorWorkPlanSchedule> list) {
        for (DoctorWorkPlanSchedule entity : list) {
            doctorWorkPlanScheduleDao.insert(entity);
        }
    }
    @Override
    public ArrayList<HashMap> selectDoctorScheduleByDeptSubIdAndDate(Map param) {
        // 获取查询结果
        /**
         * map => {
         *     "date": "2025-02-12",
         *     "deptSubId": 1
         * }
         * 结果如下
         * [{"workPlanId":117,"slot":1,"doctorName":"韩倩倩","doctorId":20,"maximum":3},
         * {"workPlanId":117,"slot":2,"doctorName":"韩倩倩","doctorId":20,"maximum":3},
         * {"workPlanId":117,"slot":3,"doctorName":"韩倩倩","doctorId":20,"maximum":3},
         * {"workPlanId":123,"slot":1,"doctorName":"赵六","doctorId":88,"maximum":2},
         * {"workPlanId":123,"slot":2,"doctorName":"赵六","doctorId":88,"maximum":2},
         * {"workPlanId":123,"slot":3,"doctorName":"赵六","doctorId":88,"maximum":2}]
         * */
        ArrayList<HashMap> list = doctorWorkPlanScheduleDao.selectDoctorScheduleByDeptSubIdAndDate(param);
//            String jsonStr = JSONUtil.toJsonStr(list);
//            System.out.println(jsonStr);

        // 结果映射表，Key: doctorId，Value: 该医生的 HashMap
        LinkedHashMap<Integer, HashMap> doctorMap = new LinkedHashMap<>();

        // 遍历查询结果并整理数据
        for (HashMap map : list) {
            int doctorId = MapUtil.getInt(map, "doctorId");
            int slot = MapUtil.getInt(map, "slot");

            // 获取医生记录
            HashMap doctor = doctorMap.computeIfAbsent(doctorId, k -> {
                HashMap newDoctor = new HashMap<>(map);
                newDoctor.put("slot", new ArrayList<Boolean>(Collections.nCopies(15, Boolean.FALSE)));
                return newDoctor;
            });

            // 更新 slot 时段
            ArrayList<Boolean> slotList = (ArrayList<Boolean>) doctor.get("slot");
            if (slot >= 1 && slot <= 15) {
                slotList.set(slot - 1, Boolean.TRUE);
            }
        }

        // 返回医生数据列表
        return new ArrayList<>(doctorMap.values());
    }

    @Override
    public void insert(ArrayList<DoctorWorkPlanSchedule> list) {


        //保存详细出诊计划到doctorWorkPlanSchedule表
        insertDoctorWorkPlanSchedule(list);
        //避免患者端挂号出现超售的现象，将出诊计划保存到redis中
        addScheduleCacheToRedis(list);
    }
    private  void addScheduleCacheToRedis(ArrayList<DoctorWorkPlanSchedule> list){
        int workPlanId = list.get(0).getWorkPlanId();
        ArrayList<HashMap> scheduleList = doctorWorkPlanScheduleDao.selectDoctorScheduleByWorkPlanId(workPlanId);
        for (HashMap schedule : scheduleList) {
            cacheScheduleToRedis(schedule);
        }


    }

    private void cacheScheduleToRedis(HashMap schedule) {
        int scheduleId = MapUtil.getInt(schedule, "scheduleId");
        int slot = MapUtil.getInt(schedule, "slot");
        String date = MapUtil.getStr(schedule, "date");
        String key=WORK_PLAN_SCHEDULE_KEY+scheduleId;
        redisTemplate.opsForHash().putAll(key,schedule);
        // 获取时间段对应的起始时间
        String time = APPOINTMENT_SLOT.get(String.valueOf(slot));
        // 设置缓存过期时间，保存的单位是秒
        setCacheExpiration(key, date, time);
    }

    private void setCacheExpiration(String key, String date, String time) {
        Date expirationTime = DateUtil.parse(date + " " + time);
        redisTemplate.expireAt(key, expirationTime);

    }
   /* private void addScheduleCacheToRedis(ArrayList<DoctorWorkPlanSchedule> list) {
        // 如果list为空，直接返回
        if (CollectionUtils.isEmpty(list)) {
            return;
        }
        //获取WorkPlanId
        int workPlanId = list.get(0).getWorkPlanId();
        // 查询数据库记录，避免在循环中多次查询数据库
        ArrayList<HashMap> scheduleList = doctorWorkPlanScheduleDao.selectDoctorScheduleByWorkPlanId(workPlanId);
        if (CollectionUtils.isEmpty(scheduleList)) {
            return; // 如果查询结果为空，直接返回
        }
        // 遍历查询结果并缓存到 Redis
        for (HashMap schedule : scheduleList) {
            cacheScheduleToRedis(schedule);
        }
    }*/
}
